home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-21 | 34.9 KB | 1,399 lines | [TEXT/ALFA] |
- ####################################################################################
- # #
- # Modula.tcl: macros and bindings for Modula 2 programmers #
- # #
- # Usage: See "Modula Help" #
- # #
- # Programing: #
- # First implementation was made by Juerg Thoeny <thoeny@ito.umnw.ethz.ch> #
- # Further improvementes made by Andreas Fischlin <fischlin@ito.umnw.ethz.ch> #
- # #
- # Author Date Modification #
- # ------ ---- ------------ #
- # af 21.05.95 Initialization for new Alpha >= 6.0b7 fixed #
- # All module templates fixed to behave usefully #
- # af 01.09.95 Initialization for new Alpha >= 6.01 fixed #
- # All module templates fixed to behave usefully #
- # af 10.06.96 Fixed a few Modula-2 tcl bugs (see SysEcol #
- # bug list) #
- # af 24.06.96 Fixed a indentation and mark file bugs (see SysEcol #
- # bug list) #
- # #
- # If you make improvements to this code, please send them to us! #
- # via E-Mail: RAMSES@ito.umnw.ethz.ch #
- # #
- ####################################################################################
-
- # Global Alpha stuff
-
- #set modMenu "•400"
- set m2Menu "M2"
- set M2CommentPreString "(*"
- set M2CommentSufString "*)"
-
- set modeMenus(M2) m2Menu
- lappend allModeMenus m2Menu
- lappend modeSuffixes {*.mod} { set winMode M2 }
- lappend modeSuffixes {*.MOD} { set winMode M2 }
- lappend modeSuffixes {*.def} { set winMode M2 }
- lappend modeSuffixes {*.DEF} { set winMode M2 }
- set M2modeVars(wordBreakPreface) {[^a-zA-Z0-9]}
- set M2modeVars(wordBreak) {[a-zA-Z0-9]+}
- set M2modeVars(elecRBrace) {0}
- set M2modeVars(electricSemi) {0}
- set M2modeVars(elecLBrace) {0}
- set M2modeVars(wordWrap) {1}
- set M2modeVars(prefixString) {(*}
- set M2modeVars(suffixString) {*)}
- set M2modeVars(funcExpr) {^[ |\t]*PROCEDURE[ ]*([a-zA-Z0-9]*)}
- set M2modeVars(optionIsMeta) {1}
- set M2modeVars(tagFile) "$HOME:modTAGS"
- set M2modeVars(funcTitle) {PROC}
- lappend modes M2
- #buildModeFlagMenu
-
- # Modula 2 stuff
-
- # template bodys. Note, % means next line. To customize the template expansion, find the string
- # "M2 TEMPLATES". Procedure and module templates are "directly coded". Be careful with customizing.
-
- set templateBodys(CASE) " OF%| (*. .*):% (*. .*);%| (*. .*):% (*. .*);%ELSE% (*. .*);%END(*CASE*);"
- set templateBodys(FOR) " := TO DO%END(*FOR*);"
- set templateBodys(WHILE) " () DO%END(*WHILE*);"
- set templateBodys(WITH) " DO%END(*WITH*);"
- set templateBodys(REPEAT) "%UNTIL ();"
- set templateBodys(IF) " THEN%ELSE%END(*IF*);"
- set templateBodys(FROM) " IMPORT ;"
-
-
- # This procedure will be called on the activate event.
- proc handleM2ErrToken {} {
- global M2TokenFile
- if {[file exists "$M2TokenFile"]} {
- source "$M2TokenFile"
- removeFile "$M2TokenFile"
- }
-
- }
-
- # configuration stuff
-
- set defaultFont Programmer
-
- set M2Loaded {0}
-
-
- proc defineIndentation {} {
- global M2RightShift
- global M2LeftShift
- set maxTabWidth 31
- if {[info exists M2RightShift]} then {
- set defltRIndent $M2RightShift
- } else {
- set defltRIndent " "
- }
- set Defltcount [string length $defltRIndent]
- set prompt "By how many spaces shall «Tab»/«Shift right» move text?"
- if {[catch {getline $prompt $Defltcount } count]} then {}
- if {$count == ""} then {return}
- set intCount ""
- catch { set intCount [expr int($count)]}
- if {$intCount == $count} then {
- if {[expr (0 <= $intCount) & ($intCount <= $maxTabWidth)]} then {
- # Now create the variables to make them accessible immediately
- set M2RightShift ""
- for {set i 0} {$i < $count} {incr i} {
- set M2RightShift "$M2RightShift "
- }
- set M2LeftShift ""
- for {set i 0} {$i < $count} {incr i; incr i} {
- set M2LeftShift "$M2LeftShift "
- }
- if {($M2LeftShift == "") & ($M2RightShift != "")} then {
- set M2LeftShift " "
- }
- addDef M2RightShift $M2RightShift
- addDef M2LeftShift $M2LeftShift
- set msg "«Tab»/«Shift right» shifts selection by [string length $M2RightShift],"
- set msg "$msg «Shift left» shifts it by [string length $M2LeftShift] spaces."
- alertnote $msg
- } else {
- alertnote "Please enter a number in range 0..$maxTabWidth"
- catch { unset M2RightShift}
- catch { unset M2LeftShift}
- }
- } else {
- set msg "'$count' is not an integer!"
- set msg "$msg Please enter a number in range 0..$maxTabWidth"
- alertnote $msg
- catch { unset M2RightShift}
- catch { unset M2LeftShift}
- }
- }
-
-
-
- proc defineWrapRightMargin {} {
- global M2WrapRightMargin
- set minWTRM 2
- set maxWTRM 256
- if {[info exists M2WrapRightMargin]} then {
- set defltWTRM $M2WrapRightMargin
- } else {
- set defltWTRM 65
- }
- set prompt "At which right margin (column) shall text be wrapped?"
- if {[catch {getline $prompt $defltWTRM } userWTRM]} then {}
- if {$userWTRM == ""} then {return}
- set intWTRM ""
- catch { set intWTRM [expr int($userWTRM)]}
- if {$intWTRM == $userWTRM} then {
- if {[expr ($minWTRM <= $intWTRM) & ($intWTRM <= $maxWTRM)]} then {
- # it's now ok
- set M2WrapRightMargin "$userWTRM"
- addDef M2WrapRightMargin $M2WrapRightMargin
- } else {
- alertnote "Please enter a number in range $minWTRM..$maxWTRM"
- catch { unset M2WrapRightMargin}
- }
- } else {
- set msg "'$M2WrapRightMargin' is not an integer!"
- set msg "$msg Please enter a number in range $minWTRM..$maxWTRM"
- alertnote $msg
- catch { unset M2WrapRightMargin}
- }
- }
-
-
-
- proc configureLaunching {} {
- global M2Home
- global M2TokenFile
- global M2System
- global M2ErrFile
- global M2errDOKFile
- global USER_STARTUP
-
- set msg "Please configure the Modula-2 environment for the launching of a shell "
- set msg "$msg and the compiler support."
- alertnote $msg
-
- if {[catch {getfile "Open a M2 shell (MacMETH or RAMSES)"} path]} then {
- # immediately quit routine
- return 1
- }
- set fileDir [file dirname $path]
- addDef M2System $path
- addDef M2Home $fileDir
- addDef M2TokenFile "$fileDir:token.ALPHA"
- addDef M2ErrFile "$fileDir:err.ALPHA"
- # Now create the variables to make them accessible immediately
- set M2System $path
- set M2Home $fileDir
- set M2TokenFile "$fileDir:token.ALPHA"
- set M2ErrFile "$fileDir:err.ALPHA"
-
- if {[catch {getfile "Locate 'ErrList.DOK' (look in ƒ M2Tools)"} errpath]} {
- # immediately quit routine
- return 1
- }
- addDef M2errDOKFile $errpath
- # Now create the variable to make it accessible immediately
- set M2errDOKFile $errpath
- }
-
-
-
- proc configure {} {
- global M2Author
- global M2RightShift
- global M2WrapRightMargin
-
- set prompt "Your first and last name please:"
- if {[info exists M2Author]} then {
- set defltUser $M2Author
- } else {
- set defltUser "First Last"
- }
- if {[catch {getline $prompt $defltUser } author]} then {}
- if {$author == ""} then {return}
- addDef M2Author $author
- # Now create the variable to make it accessible immediately
- set M2Author $author
-
- # Now define indentation
- defineIndentation
- if {![info exists M2RightShift]} then {return}
-
- # Now define right text wrap margin
- defineWrapRightMargin
- if {![info exists M2WrapRightMargin]} then {return}
- }
-
-
- # Make sure configuration is ok
- if {[catch {set M2ConfTest "$M2System"}]} then {
- configureLaunching
- } elseif {![file exists "$M2System"]} then {
- set shellName [file tail "$M2System"]
- set quest "Could not find the Modula-2 shell “$shellName“. "
- append quest "Do you wish to reconfigure the Modula-2 environment?"
- if {[askyesno $quest] == "yes"} then {
- configureLaunching
- }
- }
-
-
- # Make sure M2Author is defined
- while {![info exists M2Author]} {
- configure
- }
-
- # Make sure M2RightShift is defined
- while {![info exists M2RightShift]} {
- defineIndentation
- }
-
- # Make sure M2WrapRightMargin is defined
- while {![info exists M2WrapRightMargin]} {
- defineWrapRightMargin
- }
-
-
- # Basic M2 binding to open work object
- bind '0' <z> openM2WorkFiles
-
- set returnCompleteWords "FOR FROM"
- set returnWords "$returnCompleteWords BEGIN CONST ELSE WHILE IF PROCEDURE WITH"
- set returnWords "$returnWords MODULE REPEAT TYPE VAR"
-
- set spaceWords "CASE WHILE FOR IF REPEAT FROM PROCEDURE IMPLEMENTATION DEFINITION LOOP MODULE WITH"
-
- set expandWords "ARRAY BOOLEAN BITSET CHAR CARDINAL DO END LONGCARD LONGINT LONGREAL"
- set expandWords " $expandWords IMPORT INTEGER OF POINTER REAL RECORD RETURN TO"
- set expandWords [lsort "$returnWords $spaceWords $expandWords"]
-
- set m2ErrRing ""
-
- # M2 KEY BINDINGS
- bind '1' <z> launchShell
- bind '2' <z> launchShellAndSimulate
- bind '0' <z> openWorkFiles
- bind 0x24 <s> carriageReturn "M2"
- bind 0x24 modulaReturn "M2"
- bind 0x31 modulaSpace "M2"
- bind 0x33 <z> killWholeLine "M2"
- bind 0x31 <e> expandSpace "M2"
- bind 0x25 <e> markLine "M2"
- bind 0x2e <z> markLine "M2"
- bind 0x7c <z> forwardWord "M2"
- bind 0x7b <z> backwardWord "M2"
- bind 0x30 modulaTab "M2"
- bind 0x73 <z> beginningOfBuffer "M2"
- bind 0x77 <z> endOfBuffer "M2"
- bind 'g' <z> nextPlaceholder "M2"
- bind 'g' <sz> prevPlaceholder "M2"
- bind '\]' <o> m2ShiftRight "M2"
- bind 'r' <z> m2ShiftRight "M2"
- bind '\[' <o> m2ShiftLeft "M2"
- bind 'l' <z> m2ShiftLeft "M2"
- bind 'k' <z> commentSelection "M2"
- bind 'k' <sz> uncommentSelection "M2"
- bind 'a' <sz> wrapText "M2"
- bind 'a' <z> wrapComment "M2"
- bind 0x33 <o> killLine "M2"
-
-
- # 'M2' programming mode
-
- proc setM2Mode {} {
- changeMode "M2"
- }
-
- proc killWholeLine {} {
- goto [lineStart [getPos]]
- killLine
- }
-
- #================================================================================
- proc actionOnReturn {} {
- set pos [getPos]
- deleteText $pos [selEnd]
- goto $pos
- endOfLine
- carriageReturn
- }
-
- #================================================================================
- proc modulaTab {} {
- global M2RightShift
- insertText $M2RightShift
- }
-
- proc wrapComment {} {
- global leftFillColumn
- global M2RightShift
- global M2WrapRightMargin
- global fillColumn
- set increment [string length $M2RightShift]
- set pos [getPos]
- set end [selEnd]
- if {$pos == $end} {
- balance
- set pos [getPos]
- set end [selEnd]
- if {$pos == $end} {
- beep
- message "Please make a selection"
- return
- }
- }
- set firstPos [lindex [search -s -r 1 -f 1 -n -- "\\(\\*" $pos] 0]
- if {$firstPos == ""} {
- beep
- message "No comment in selection"
- return
- }
- if {$firstPos > $end} {
- beep
- message "Empty selection?"
- return
- }
- set lastPos [matchIt "\(" [expr $firstPos +$increment]]
- if {$lastPos > $end} {
- beep
- message "Comment must be completely inside selection"
- return
- }
- goto [expr $firstPos + $increment]
- carriageReturn
- set lastPos [matchIt "\(" [expr $firstPos +$increment]]
- select [getPos] [expr $lastPos +1]
- set tmpLeftFillColumn $leftFillColumn
- set leftFillColumn [expr [lindex [posToRowCol $firstPos] 1] + $increment]
- set tmpfillColumn $fillColumn
- set fillColumn $M2WrapRightMargin
- fillRegion
- set leftFillColumn $tmpLeftFillColumn
- set fillColumn $tmpfillColumn
- goto [expr [matchIt "\(" [expr $firstPos +$increment]] -1]
- carriageReturn
- unIndent
- set topTxtLeftMargRow [lindex [posToRowCol $firstPos] 0]
- set topTxtLeftMargRow [expr $topTxtLeftMargRow +1]
- set topTxtLeftMarg [rowColToPos $topTxtLeftMargRow 0]
- set textBeg [expr [lindex [posToRowCol $firstPos] 1] + $increment]
- set count [expr $textBeg]
- goto $topTxtLeftMarg
- for {set i 0} {$i < $count} {incr i} {
- deleteChar
- }
- goto $firstPos
- }
-
-
- proc wrapText {} {
- global leftFillColumn
- global fillColumn
- global M2WrapRightMargin
- global fillColumn
- set pos [getPos]
- set end [selEnd]
- if {$pos == $end} {
- beep
- message "Please make a selection"
- return
- }
- set firstPos [search -s -r 1 -f 1 -n -- "\[\^ \\t\\r\]" $pos]
- if {$firstPos > $end} {
- beep
- message "Empty selection?"
- return
- }
- set tmpLeftFillColumn $leftFillColumn
- set tmpfillColumn $fillColumn
- set leftFillColumn [lindex [posToRowCol $firstPos] 1]
- set fillColumn $M2WrapRightMargin
- fillRegion
- set leftFillColumn $tmpLeftFillColumn
- set fillColumn $tmpfillColumn
-
- set topTxtLeftMargRow [lindex [posToRowCol $firstPos] 0]
- set topTxtLeftMarg [rowColToPos $topTxtLeftMargRow 0]
- set textBeg [lindex [posToRowCol $firstPos] 1]
- set count [expr $textBeg]
- goto $topTxtLeftMarg
- for {set i 0} {$i < $count} {incr i} {
- deleteChar
- }
- goto $pos
- }
-
-
- #================================================================================
- proc nextPlaceholder {} {
- searchPlaceholder 1
- }
- proc prevPlaceholder {} {
- searchPlaceholder 0
- }
-
- proc commentSelection {} {
- set pos [getPos]
- set end [selEnd]
- if {$pos == $end} {
- beep
- message "Please make a selection"
- return
- }
- replaceText $pos $end "\(\*\. [getText $pos $end] \.\*\)"
- select $pos [expr $end + 8]
- }
-
- proc uncommentSelection {} {
- set pos [getPos]
- set end [selEnd]
- if {$pos == $end} {
- beep
- message "Please make a selection"
- return
- }
- if {[expr $end - $pos] < 8} {
- beep
- message "Selection to small"
- return
- }
- if {[getText $pos [expr $pos + 4]] != "(*. "} {
- beep
- message "Wrong left comment-start in selection"
- return
- }
- if {[getText [expr $end - 4] $end] != " .*)"} {
- beep
- message "Wrong right comment-start in selection"
- return
- }
- replaceText [expr $end - 4] $end ""
- replaceText $pos [expr $pos + 4] ""
- select $pos [expr $end - 8]
- }
-
- #================================================================================
- proc m2ShiftLeft {} {
- global M2LeftShift
- set start [lineStart [getPos]]
- set end [nextLineStart [expr [selEnd] -1]]
- set increment [string length $M2LeftShift]
- for {set i $start} {$i < $end} {set i [nextLineStart $i]} {
- if {[getText $i [expr $i + $increment]] != $M2LeftShift} {
- beep
- return
- }
- }
- select $start $start
- for {set i $start} {$i < $end} {set i [nextLineStart $i]} {
- incr end -$increment
- goto $i
- replaceText $i [expr $i + $increment] ""
- }
- goto $start
- select $start $end
- }
-
-
- #================================================================================
- proc m2ShiftRight {} {
- global M2RightShift
- set start [lineStart [getPos]]
- set end [nextLineStart [expr [selEnd] -1]]
- select $start $start
- set increment [string length $M2RightShift]
- for {set i $start} {$i < $end} {set i [nextLineStart $i]} {
- incr end $increment
- goto $i
- insertText $M2RightShift
- }
- goto $start
- select $start $end
- }
-
- #================================================================================
- proc searchPlaceholder {dir} {
- set pos [getPos]
- saveVars
- set depth 1
- if ($dir==1) {
- set push "(*."
- set pop ".*)"
- if {[getSelect] != ""} {
- incr pos
- }
- set add 3;
- set position [search -s -r 1 -f $dir -n -- "\\(\\*\\." $pos]
- } else {
- set push ".*)"
- set pop "(*."
- set pos [expr [selEnd]-4]
- set add -3;
- set position [search -s -r 1 -f $dir -n -- "\\.\\*\\)" $pos]
- }
- if {$position != ""} {
- set pos [expr "[lindex $position 0]+$add"]
- set str "(\\(\\*\\.)|(\\.\\*\\))"
- while {1} {
- set limits [search -s -r 1 -f $dir -n -- "$str" $pos]
- if {$limits == ""} {
- message "Not matched placeholder"
- beep
- restoreVars
- return
- }
- set pos [lindex $limits 0]
- set c [getText $pos [expr "$pos+3"]]
- if {$c == $push} {
- incr depth
- }
- if {$c == $pop} {
- if {[set depth [expr $depth-1]] == 0} {
- if ($dir==1) {
- select [lindex $position 0] [expr "$pos+3"]
- } else {
- select $pos [lindex $position 1]
- }
- restoreVars
- return
- }
- }
- set pos [expr $pos+$add]
- if {$pos > [maxPos]} {
- alertnote "makro error, please contact jth"
- }
- }
- } else {
- message "no more placeholders"
- beep
- }
- restoreVars
- }
-
- #===========================================================================
- # Modula routines.
- #===========================================================================
- menu -n $m2Menu {
- "openWorkFiles"
- "findNextError"
- "launchShell"
- "launchShellAndSimulate"
- "(-"
- "DefToMod"
- "commentSelection"
- "uncommentSelection"
- "m2ShiftRight"
- "m2ShiftLeft"
- "wrapComment"
- "wrapText"
- "(-"
- {menu -n templates -m {
- "DEFINITION"
- "FOR"
- "IF"
- "IMPLEMENTATION"
- "PROCEDURE"
- "MODULE"
- "WHILE"
- "WITH"
- }
- }
- "configureLaunching"
- "configure"
- }
-
- #================================================================================
- proc fileExt {} {
- set fileName [lindex [winNames -f] 0]
- if {[string last "." $fileName] == -1} {
- return " "
- }
- set fileName [split $fileName .]
- return [lindex $fileName [expr "[llength $fileName]-1"]]
- }
-
-
- #================================================================================
- proc removeM2ErrMarks {fileName} {
- global m2ErrRing
- while 1 {
- set ind [lsearch $m2ErrRing "*$fileName*"]
- if {$ind == "-1"} {
- return
- }
- set m2ErrRing [lreplace $m2ErrRing $ind $ind]
- }
- }
-
- #================================================================================
- proc removeAllM2ErrMarks {} {
- global m2ErrRing
- while {[llength $m2ErrRing] != 0} {
- removeTMark [lindex [lindex $m2ErrRing 0] 1]
- set m2ErrRing [lreplace $m2ErrRing 0 0]
- }
- }
-
- #================================================================================
- proc actM2ErrMsg {} {
- global m2ErrRing
- global errList
- beep
- if {[llength $m2ErrRing] == "0"} {
- message "No Modula errors"
- beep
- return
- }
- set num [lindex [lindex $m2ErrRing 0] 2]
- regexp "$num\[ \]+(\[^\n\]*)" $errList dummyStr errMsg
- set errMsg [string range $errMsg 0 40]
- message $errMsg
- }
-
-
- #================================================================================
- proc findNextError {} {
- global m2ErrRing
- global errList
- set fileName [lindex [winNames -f] 0]
- if {[llength $m2ErrRing] == "0"} {
- beep
- message "No more errors"
- return
- }
- set first [lindex $m2ErrRing 0]
- set m2ErrRing [lreplace $m2ErrRing 0 0]
- set m2ErrRing [lappend m2ErrRing $first]
- gotoTMark [lindex [lindex $m2ErrRing 0] 1]
- if {$fileName != [lindex [winNames -f] 0]} {
- centerRedraw
- }
- selectCurWord
- actM2ErrMsg
- }
-
-
-
- #================================================================================
- set loadM2ErrorMsg ""
-
- proc openM2WorkFiles {} {
- saveVars
- global m2ErrRing
- global errList
- global M2ErrFile
- global M2errDOKFile
- global M2Home
- global loadM2ErrorMsg
- removeAllM2ErrMarks
- set m2ErrRing ""
- bind 'j' <z> findNextError "M2"
- bind 'e' <z> findNextError "M2"
- set loadM2ErrorMsg "opening or reading $M2errDOKFile"
- set msgFile [open "$M2errDOKFile"]
- set errList [read $msgFile]
- close $msgFile
- set loadM2ErrorMsg "opening or reading $M2ErrFile"
- set errFile [open "$M2ErrFile"]
- if {[gets $errFile lineStr] < 1} {
- beep
- message "No Errors found"
- close $errFile
- return
- }
- set numErrs 0
- set i 1
- while {$lineStr == "NEW"} {
- if {[gets $errFile lineStr] < 1} {
- break
- }
- set loadM2ErrorMsg "opening $lineStr"
- set ind [lsearch [winNames -f] $lineStr]
- if {$ind == -1} {
- if {[file exists $lineStr]} {
- edit "$lineStr"
- } else {
- edit "$M2Home$lineStr"
- }
- } else {
- bringToFront [lindex [winNames] $ind]
- }
- set loadM2ErrorMsg "opening or reading $M2ErrFile"
- if {[gets $errFile lineStr] < 1} {
- break
- }
- set fileName [lindex [winNames -f] 0]
- while {($lineStr != "NEW") && ($lineStr != "END")} {
- scan $lineStr "%d %d" pos errNum
- if {[gets $errFile lineStr] < 1} {
- break
- }
- goto $pos
- createTMark "errMark$i" $pos
- set m2ErrRing [lappend m2ErrRing [list $fileName errMark$i $errNum]]
- set i [expr $i+1]
- set numErrs [expr $numErrs+1]
- }
- }
- if {$numErrs < 1} {
- beep
- message "No Errors found"
- close $errFile
- return
- }
- close $errFile
- gotoTMark errMark1
- restoreVars
- set pos [getPos]
- centerRedraw
- selectCurWord
- actM2ErrMsg
- }
- proc openWorkFiles {} {
- global loadM2ErrorMsg
- if {[catch openM2WorkFiles]} {
- beep
- alertnote "Error: $loadM2ErrorMsg"
- }
- }
-
- #================================================================================
- proc callM2 {} {
- global M2System
- launch -f "$M2System"
- }
- proc launchShell {} {
- if {[catch callM2]} {
- beep
- alertnote "Call of M2 went wrong.\rCheck configuration."
- }
- }
- proc launchShellAndSimulate {} {
- if {[catch callM2]} {
- beep
- alertnote "Call of M2 went wrong.\rCheck configuration."
- }
- dosc -n " RAMSES Shell 2.2b6" -k 'DMEv' -e 'COMP' -s "gaga" -r
- }
-
-
- #================================================================================
- proc markLine {} {
- set pos [getPos]
- set start [lineStart $pos]
- set end [nextLineStart $pos]
- select $start $end
- }
-
- #================================================================================
- proc trim {text} {
- return [string trim $text]
- }
-
- #================================================================================
- proc getCurLine {} {
- set pos [getPos]
- set start [lineStart $pos]
- set end [nextLineStart $pos]
- set text [getText $start $end]
- regexp "(\[^\r\]*)\r?" $text dummyText text
- return $text
- }
-
- #================================================================================
- proc getCurWord {} {
- set pos [getPos]
- backwardWord
- set bPos [getPos]
- if {$bPos == 1} {
- set text " "
- regexp "\[A-Za-z\]" [getText 0 1] text
- if {$text != " "} {
- set bPos 0
- }
- }
-
- forwardWord
- set fPos [getPos]
- goto $pos
- return [getText $bPos $fPos]
- }
-
- #================================================================================
- proc selectCurWord {} {
- set pos [getPos]
- set char [lookAt [expr "$pos-1"]]
- if {[regexp "\[A-Za-z\]" $char] == 0} {
- set bPos [expr "$pos+1"]
- } else {
- backwardWord
- set bPos [getPos]
- if {$bPos == 1} {
- set text " "
- regexp "\[A-Za-z\]" [getText 0 1] text
- if {$text != " "} {
- set bPos 0
- }
- }
-
- forwardWord
- }
- select $bPos [getPos]
- }
-
- #================================================================================
- proc firstWord {text} {
- regexp "\[ |\t\]*(\[A-Za-z0-9_\]*)(.*)" $text text firstWd rest
- return $firstWd
- }
- proc restWord {text} {
- regexp "\[ |\t\]*(\[A-Za-z0-9_\]*)(.*)" $text text firstWd rest
- return $rest
- }
-
- #================================================================================
- proc initials {} {
- global M2Author
- return "[string index [lindex "$M2Author" 0] 0][string index [lindex "$M2Author" 1] 0]"
- }
-
- #================================================================================
- proc unIndent {} {
- global M2RightShift
- set count [string length $M2RightShift]
- for {set i 0} {$i < $count} {incr i} {
- backSpace
- }
- }
-
- # M2 TEMPLATES
- #================================================================================
- proc insertTemplateBody {name} {
- global templateBodys
- set pos [getPos]
- set start [lineStart $pos]
- set indent [eval "getText [join [search -s -r 1 -f 1 -n -- "\[ \\t\]*" $start]]"]
- insertText [lindex [split "$templateBodys($name)" "%"] 0]
- foreach bodyLine [lrange [split "$templateBodys($name)" "%"] 1 100] {
- insertText \r${indent}${bodyLine}
- }
- goto $pos
- }
- #================================================================================
- proc cASE {} {
- insertText "CASE"
- templateCASE
- }
- proc templateCASE {} {
- insertTemplateBody CASE
- goto [expr [getPos]+1]
- }
-
- #================================================================================
- proc fOR {} {
- insertText "FOR"
- templateFOR
- }
- proc templateFOR {} {
- insertTemplateBody FOR
- goto [expr [getPos]+1]
- }
-
- #================================================================================
- proc wHILE {} {
- insertText "WHILE"
- templateWHILE
- }
- proc templateWHILE {} {
- insertTemplateBody WHILE
- goto [expr [getPos]+2]
- }
-
- #================================================================================
- proc wITH {} {
- insertText "WITH"
- templateWITH
- }
- proc templateWITH {} {
- insertTemplateBody WITH
- goto [expr [getPos]+1]
- }
-
- #================================================================================
- proc iF {} {
- insertText "IF"
- templateIF
- }
-
- proc templateIF {} {
- insertTemplateBody IF
- goto [expr [getPos]+1]
- }
-
- #================================================================================
- proc rEPEAT {} {
- insertText "REPEAT"
- templateREPEAT
- }
- proc templateREPEAT {} {
- insertTemplateBody REPEAT
- indentOnReturn
- }
-
- #================================================================================
- proc fROM {} {
- insertText "FROM"
- templateFROM
- }
- proc templateFROM {} {
- insertTemplateBody FROM
- goto [expr [getPos]+1]
- }
-
- #================================================================================
- proc pROCEDURE {} {
- insertText "PROCEDURE"
- templatePROCEDURE
- }
- proc templatePROCEDURE {} {
- set winName [lindex [winNames -f] 0]
- set procName [getline "PROCEDURE Name : "]
- bringToFront $winName
- if {[string length $procName] < 1} {
- return;
- }
- set pos [expr "[getPos]+1+[string length $procName]"]
- insertText " $procName;"
- if {[string toupper [fileExt]] != "DEF"} {
- carriageReturn
- insertText "BEGIN (* $procName *)"
- carriageReturn
- insertText "END $procName;"
- carriageReturn
- }
- goto $pos
- }
-
- #================================================================================
-
- # An aux proc
-
- proc askForModuleName {prompt} {
- set modName [getline "$prompt"]
- if {([string length $modName] < 1)} {
- return ""
- }
- if {[regexp {[^A-Za-z0-9]} $modName]} then {
- alertnote "The module name “$modName“ contains illegal characters!"
- return ""
- }
- if {([string length $modName] > 12)} {
- set quest "“$modName“ is too long (> 12 chars). You should stop to change it. Ok?"
- if {[askyesno $quest] == "yes"} {
- return ""
- }
- }
- return $modName
- }
-
- proc openOrMakeFile {prompt ext} {
- if {$prompt == ""} then {
- set modName "$ext"
- set modFName "$modName"
- } else {
- set modName [askForModuleName $prompt]
- set modFName "$modName.$ext"
- }
- if {$modName == ""} then { return }
- set winList [winNames]
- if { [IsInList $winList $modFName] } then {
- # File already exists and is open
- bringToFront $modFName
- } else {
- # Create new file with the proper name
- new -n $modFName
- }
- set modName [file tail $modFName]
- set modName [file rootname $modName]
- return $modName
- }
-
- #================================================================================
- proc mODULE {} {
- # Used by calling submenu M2/Templates/MODULE
- set modName [openOrMakeFile "Program MODULE Name : " "MOD"]
- if {$modName != ""} then {
- insertText "MODULE"
- modBODY $modName
- }
- }
-
- proc templateMODULE {} {
- # Used while expanding keyword MODULE
- set modName [askForModuleName "Program MODULE Name: "]
- if {$modName != ""} then {
- modBODY $modName
- }
- }
-
- #================================================================================
- proc modBODY {modName} {
- global M2RightShift
- if {[string length $modName] < 1} {
- return;
- }
- insertText " $modName;"
- carriageReturn
- carriageReturn
- insertText $M2RightShift
- insertText "(*"
- carriageReturn
- insertText $M2RightShift
- insertText "Implementation and Revisions:"
- carriageReturn
- insertText "============================"
- carriageReturn
- carriageReturn
- insertText "Author Date Description"
- carriageReturn
- insertText "------ ---- -----------"
- carriageReturn
- insertText "[initials] [format "%-11s" "[lindex [mtime [now] short] 0]"]"
- insertText "First implementation"
- carriageReturn
- unIndent
- insertText "*)"
- carriageReturn
- unIndent
- set pos [getPos]
- carriageReturn
- insertText "BEGIN (* $modName *)"
- carriageReturn
- insertText "END $modName."
- carriageReturn
- goto $pos
- indentOnReturn
- }
-
- #================================================================================
- proc defBODY {modName} {
- global M2RightShift
- global M2Author
- if {[string length $modName] < 1} {
- return;
- }
- insertText " $modName;"
- carriageReturn
- carriageReturn
- insertText $M2RightShift
- insertText "(*******************************************************************"
- carriageReturn
- carriageReturn
- insertText $M2RightShift
- insertText "Module $modName (Version 1.0)"
- carriageReturn
- carriageReturn
- insertText $M2RightShift
- insertText "Copyright (c) 1992 by $M2Author and Swiss"
- carriageReturn
- insertText "Federal Institute of Technology Zurich ETHZ"
- carriageReturn
- carriageReturn
- unIndent
- insertText "Version written for:"
- carriageReturn
- insertText $M2RightShift
- insertText "MacMETH_V3.2 (1-Pass Modula-2 implementation)"
- carriageReturn
- carriageReturn
- unIndent
- insertText "Purpose (*. purpose .*)"
- carriageReturn
- carriageReturn
- insertText "Remarks (*. remarks .*)"
- carriageReturn
- carriageReturn
- carriageReturn
- insertText "Programming"
- carriageReturn
- carriageReturn
- insertText $M2RightShift
- insertText "o Design"
- carriageReturn
- insertText $M2RightShift
- insertText "$M2Author [lindex [mtime [now] short] 0]"
- carriageReturn
- carriageReturn
- unIndent
- insertText "o Implementation"
- carriageReturn
- insertText $M2RightShift
- insertText "$M2Author [lindex [mtime [now] short] 0]"
- carriageReturn
- carriageReturn
- carriageReturn
- unIndent
- insertText "Swiss Federal Institute of Technology Zurich ETHZ"
- carriageReturn
- insertText "CH-8092 Zurich"
- carriageReturn
- insertText "Switzerland"
- carriageReturn
- carriageReturn
- insertText "Last revision of definition: [lindex [mtime [now] short] 0] [initials]"
- carriageReturn
- carriageReturn
- unIndent
- unIndent
- insertText "*******************************************************************)"
- carriageReturn
- carriageReturn
- set pos [getPos]
- unIndent
- carriageReturn
- insertText "END $modName."
- carriageReturn
- goto $pos
- indentOnReturn
- }
-
- #================================================================================
- proc defToMod {} {
- set winName [lindex [winNames -f] 0]
- if {$winName == ""} return
- set modName [getText 0 [nextLineStart 0]]
- if {[lindex $modName 0] != "DEFINITION"} {
- beep
- alertnote "wrong window"
- return
- }
- if {[lindex $modName 1] != "MODULE"} {
- beep
- alertnote "wrong window"
- return
- }
- set modName [lindex $modName 2]
- set modName [string range $modName 0 [expr [string length $modName] - 2]]
- if {$modName == ""} {
- beep
- alertnote "wrong window"
- return
- }
- set modName [openOrMakeFile "" "$modName.MOD"]
- insertText "IMPLEMENTATION MODULE "
- modBODY $modName
- set newName [lindex [winNames -f] 0]
- unIndent
- bringToFront $winName
- set pos [search -s -r 1 -f 1 -i 0 -n -- "FROM|IMPORT" 0]
- set end [search -s -r 1 -f 1 -i 0 -n -- "TYPE|PROCEDURE|VAR|CONST|END" 0]
- if {$pos != ""} {
- set text [getText [lineStart $pos] [lineStart $end]]
- insertText -w $newName $text
- }
- set end 0
- set matchStr "PROCEDURE\[ \\t\]*\[A-Za-z0-9\]+\[ \\t\]*(\\(\[^\\)\]*\\))?\[^\\;\]*\;"
- set pos [search -s -r 1 -f 1 -i 0 -n -- $matchStr $end]
- set end [lindex $pos 1]
- while {$pos != "" } {
- set text [getText [lineStart $pos] [nextLineStart [lindex $pos 1]]]
- insertText -w $newName $text
- set insertion [format "%[string first [lindex $text 0] $text]s" ""]
- set procName [lindex [split "[lindex $text 1]" "(;"] 0]
- insertText -w $newName $insertion
- insertText -w $newName "BEGIN (* $procName *)"
- insertText -w $newName "\r"
- insertText -w $newName $insertion
- insertText -w $newName "END $procName;"
- insertText -w $newName "\r\r"
- set pos [search -s -r 1 -f 1 -i 0 -n -- $matchStr $end]
- set end [lindex $pos 1]
- }
- bringToFront $newName
- changeMode "M2"
- }
-
-
- #================================================================================
- proc dEFINITION {} {
- # Used by calling submenu M2/Templates/DEFINITION
- set modName [openOrMakeFile "DEFINITION MODULE Name: " "DEF"]
- if {$modName != ""} then {
- insertText "DEFINITION MODULE"
- defBODY $modName
- prevPlaceholder
- prevPlaceholder
- }
- }
-
- proc templateDEFINITION {} {
- # Used while expanding keyword DEFINITION
- insertText " MODULE"
- set modName [askForModuleName "DEFINITION MODULE Name: "]
- if {$modName != ""} then {
- defBODY $modName
- prevPlaceholder
- prevPlaceholder
- }
- }
-
- #================================================================================
-
- proc iMPLEMENTATION {} {
- # Used by calling submenu M2/Templates/IMPLEMENTATION
- set modName [openOrMakeFile "IMPLEMENTATION MODULE Name : " "MOD"]
- if {$modName != ""} then {
- insertText "IMPLEMENTATION MODULE"
- modBODY $modName
- }
- }
-
- proc templateIMPLEMENTATION {} {
- # Used while expanding keyword IMPLEMENTATION
- set modName [askForModuleName "IMPLEMENTATION MODULE Name: "]
- if {$modName != ""} then {
- insertText " MODULE"
- modBODY $modName
- }
- }
-
- #================================================================================
- proc indentOnReturn {} {
- global M2RightShift
- actionOnReturn
- insertText $M2RightShift
- }
-
- #================================================================================
- proc modulaReturn {} {
- global returnWords
- global returnCompleteWords
- set line [getCurLine]
- set first [firstWord $line]
- set first [trim $first]
- if {[lsearch " $returnWords " $first] > -1} {
- if {[lsearch " $returnCompleteWords " $first] > -1} {
- set pos [getPos]
- set start [lineStart $pos]
- set leftText [getText $start $pos]
- if {$first == "FOR"} {
- if {[string first "TO" $leftText] > -1} {
- indentOnReturn
- return
- }
- if {[string first ":=" $leftText] > -1} {
- goto [expr "$start + [string first "TO" $line] + 3"]
- return
- }
- if {[string first "FOR" $leftText] > -1} {
- goto [expr "$start + [string first ":=" $line] + 3"]
- return
- }
- goto [expr "$start + [string first "FOR" $line] + 4"]
- }
- if {$first == "FROM"} {
- if {[string first "IMPORT" $leftText] > -1} {
- actionOnReturn
- return
- }
- if {[string first "FROM" $leftText] > -1} {
- goto [expr "$start + [string first "IMPORT" $line] + 7"]
- return
- }
- goto [expr "$start + [string first "FROM" $line] + 5"]
- }
- } else {
- indentOnReturn
- }
- } else {
- actionOnReturn
- }
- }
-
- #================================================================================
- proc modulaSpace {} {
- global spaceWords
- set line [getCurLine]
- set first [firstWord $line]
- set first [trim $first]
- set rest [restWord $line]
- set rest [trim $rest]
- if {[lsearch " $spaceWords " $first] > -1} {
- if {[string length $rest] > 0} {
- deleteText [getPos] [selEnd]
- insertText " "
- } else {
- if {[catch template$first]} {
- beep
- alertnote "Template for:$first not defined"
- }
- }
- } else {
- deleteText [getPos] [selEnd]
- insertText " "
- }
- }
-
- #================================================================================
- proc expandSpace {} {
- global expandWords
- set pos [getPos]
- backwardWord
- set bPos [getPos]
- if {$bPos == 1} {
- set text " "
- regexp "\[A-Za-z\]" [getText 0 1] text
- if {$text != " "} {
- set bPos 0
- }
- }
-
- forwardWord
- set fPos [getPos]
- goto $pos
- set origWord [getText $bPos $fPos]
- set word [string toupper $origWord]
- set ind [lsearch $expandWords $origWord*]
- if {$ind == -1} {
- wordCompletion
- return
- }
- set expandWord [lindex $expandWords $ind]
- if {$expandWord != $origWord} {
- replaceText $bPos $fPos $expandWord
- }
- }
-
- #================================================================================
- proc M2MarkFile {} {
- set pos 0
- while {![catch {search -s -f 1 -r 1 -m 0 -i 0 {^[ \t]*PROCEDURE} $pos} res]} {
- set start [expr [lindex $res 1] + 1]
- set end [nextLineStart $start]
- regexp "\[A-za-z\]*" [getText $start $end] text
- set pos $end
- set inds($text) [lineStart [expr $start - 1]]
- }
- if {[info exists inds]} {
- foreach f [lsort [array names inds]] {
- set next [nextLineStart $inds($f)]
- setNamedMark $f $inds($f) $next $next
- }
- }
- }
-
- #================================================================================
- # Colorize Modula code.
- #================================================================================
-
- regModeKeywords -b {(*} {*)} -c red -k blue M2 $expandWords
-
- proc colorizeM2Comments {} {
- }
-